package com.tencent.wxcloudrun.service;
import com.tencent.wxcloudrun.model.ApplyRecord;
import com.tencent.wxcloudrun.model.Product;
import com.tencent.wxcloudrun.model.User;
import com.tencent.wxcloudrun.repository.ApplyRecordRepository;
import com.tencent.wxcloudrun.repository.UserRepository;
import org.hibernate.Hibernate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Service
public class ApplyRecordService {

    @Resource
    private ApplyRecordRepository applyRecordRepository;

    @Resource
    private UserRepository userRepository;

    @Resource
    private ProductService productService;

    // 分页查询 + 查询条件
//    public Page<ApplyRecord> getApplyRecords(ApplyRecord.LoanStatus status, String phone, Pageable pageable) {
//        // 调用 repository 方法，传入查询条件和分页参数
//
//        return applyRecordRepository.findAllByStatusAndPhoneContaining(status, phone, pageable);
//    }

    /**
     * 修改申请记录状态
     * @param recordId 记录id
     * @param status 状态
     * @return ApplyRecord
     */
    public ApplyRecord modifyApplyRecordStatus(Long recordId, ApplyRecord.LoanStatus status) {
        Optional<ApplyRecord> optionalApplyRecord = applyRecordRepository.findById(recordId);
        if (optionalApplyRecord.isPresent()) {
            ApplyRecord applyRecord = optionalApplyRecord.get();
            if (status == ApplyRecord.LoanStatus.DISBURSED) {
                // 保存放款时间
                applyRecord.setDisbursedDate(LocalDateTime.now());
            }
            applyRecord.setStatus(status);
            return applyRecordRepository.save(applyRecord);
        }
        return null;
    }

    /**
     * 修改周期
     * @param recordId 记录id
     * @param weekNum 周期
     * @return ApplyRecord
     */
    public ApplyRecord modifyApplyRecordWeekNum(Long recordId, Integer weekNum) {
        Optional<ApplyRecord> optionalApplyRecord = applyRecordRepository.findById(recordId);
        if (optionalApplyRecord.isPresent()) {
            ApplyRecord applyRecord = optionalApplyRecord.get();
            // 如果已经审核通过了
            if (!applyRecord.getStatus().equals(ApplyRecord.LoanStatus.SUBMITTED)
                    && !applyRecord.getStatus().equals(ApplyRecord.LoanStatus.UNDER_REVIEW)) {
                throw new RuntimeException("已经审核过的申请，不允许再变更周期");
            }
            applyRecord.setWeekNum(weekNum);
            return applyRecordRepository.save(applyRecord);
        }
        return null;
    }


    /**
     * 修改产品
     * @param recordId 记录id
     * @param limitAmount 产品额度
     * @return ApplyRecord
     */
    public ApplyRecord modifyApplyRecordProduct(Long recordId, Integer limitAmount) {
        Optional<Product> optionalProduct = productService.getProductByLimitAmount(limitAmount);
        if (!optionalProduct.isPresent()) {
            throw new RuntimeException("未找到符合条件的产品");
        }
        Optional<ApplyRecord> optionalApplyRecord = applyRecordRepository.findById(recordId);
        if (optionalApplyRecord.isPresent()) {
            ApplyRecord applyRecord = optionalApplyRecord.get();
            // 如果已经审核通过了
            if (!applyRecord.getStatus().equals(ApplyRecord.LoanStatus.SUBMITTED)
                    && !applyRecord.getStatus().equals(ApplyRecord.LoanStatus.UNDER_REVIEW)) {
                throw new RuntimeException("已经审核过的申请，不允许再变更产品");
            }
            applyRecord.setLimitAmount(limitAmount);
            applyRecord.setProduct(optionalProduct.get());
            return applyRecordRepository.save(applyRecord);
        }
        return null;
    }

    /**
     * 修改备注
     * @param recordId 记录id
     * @param remark 备注
     * @return ApplyRecord
     */
    public ApplyRecord modifyApplyRecordRemark(Long recordId, String remark) {
        Optional<ApplyRecord> optionalApplyRecord = applyRecordRepository.findById(recordId);
        if (optionalApplyRecord.isPresent()) {
            ApplyRecord applyRecord = optionalApplyRecord.get();
            applyRecord.setRemark(remark);
            return applyRecordRepository.save(applyRecord);
        }
        return null;
    }

    public Page<ApplyRecord> searchApplyRecords(ApplyRecord.LoanStatus status, String phone, String name, Pageable pageable) {
        // 创建一个按 createdAt 字段降序排列的 Sort 对象
        Sort sort = Sort.by(Sort.Direction.DESC, "createdAt");
        // 创建包含排序规则的 Pageable 对象
        Pageable sortedPageable = PageRequest.of(
                pageable.getPageNumber(),
                pageable.getPageSize(),
                sort
        );
        Specification<ApplyRecord> spec = (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (status != null) {
                // 使用 criteriaBuilder 构建 equal 条件
                predicates.add(criteriaBuilder.equal(root.get("status"), status));
            }

            if (phone != null && !phone.isEmpty()) {
                // 使用 criteriaBuilder 构建 like 条件
                predicates.add(criteriaBuilder.like(root.get("phone"), "%" + phone + "%"));
            }
            if (name != null && !name.isEmpty()) {
                // 使用 criteriaBuilder 构建 like 条件
                predicates.add(criteriaBuilder.like(root.get("name"), "%" + name + "%"));
            }

            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };

        Page<ApplyRecord> applyRecordPage = applyRecordRepository.findAll(spec, sortedPageable);
        for (ApplyRecord applyRecord : applyRecordPage.getContent()) {
            if (applyRecord.getProduct() != null) {
                Hibernate.initialize(applyRecord.getProduct());
            }
        }
        return applyRecordPage;
    }

    public List<ApplyRecord> getUserRecords(Long userId) {
        return applyRecordRepository.findByUserIdAndDeletedFalseOrderByCreatedAtDesc(userId);
    }

    public ApplyRecord findById(Long id) {
        ApplyRecord applyRecord = applyRecordRepository.findById(id).orElse(null);
        if (applyRecord == null) {
            throw new RuntimeException("申请记录为找到, 请刷新后重试");
        }
        return applyRecord;
    }

    public void confirmApplyRecord(Long id) {
        ApplyRecord applyRecord = this.findById(id);
        applyRecord.setUserCommit(true);
        applyRecord.setUserCommitDate(LocalDateTime.now());
        applyRecordRepository.save(applyRecord);
    }

    public List<ApplyRecord> getUserRecordsByMobile(String mobile) {
        User user = userRepository.findByMobile(mobile).orElse(null);
        if (user == null) {
            throw new RuntimeException("用户未找到，请登录后重试");
        }
        return applyRecordRepository.findByUserIdAndDeletedFalseOrderByCreatedAtDesc(user.getId());
    }

    public ApplyRecord save(ApplyRecord record) {
        return applyRecordRepository.save(record);
    }

    public void deleteById(Long id) {
        applyRecordRepository.deleteById(id);
    }

    public User getUserByMobile(String mobile) {
        return userRepository.findByMobile(mobile).orElse(null);
    }
}
